/***************************************************
> Copyright (C) 2024 ==KINGYI== All rights reserved.
> File Name: send1.c
> Author:cjy
> Mail: 
> Created Time: 2024年08月05日 星期一 15时49分49秒
***************************************************/
/* 通过消息队列进程a给b发送5个学员信息，b收到后显示。
         b给a回送收到信息，a收到后结束。
*/
#include <stdio.h>       // 标准输入输出头文件
#include <string.h>      // 字符串操作头文件
#include <stdlib.h>      // 标准库头文件
#include <sys/ipc.h>     // 进程间通信头文件
#include <sys/msg.h>     // 消息队列头文件
struct msgbuf{
	long mtype;   //消息类型
	char mtext[100]; 
};
typedef struct use{
	char name[10];
	int age;
	float score;
	struct use *next;
}STU;
int main(int argc,const char* argv[])
{
	char path[50] = {0};
	key_t key = 0;//消息队列标识符
	int msgid = 0;//消息队列 ID
	int ret = 0; // 函数返回值
	printf("请输入路径:");
	scanf("%s",path);
	
	key = ftok(path,1);// 使用 ftok 生成一个唯一的 key
	if (key == -1){
		perror("ftok");
		exit(-1);	
	}
	
	msgid = msgget(key,IPC_CREAT | 0666); // 创建或获取消息队列
	if (msgid == -1){
		perror("msgget");
		exit(-1);	
	}

	STU *head = NULL;
	
	head = malloc(sizeof(STU));
	memset(head,0,sizeof(STU));
	STU *p = NULL;
	p = head;
	
        int count = 0;
        int flag = 0;
        int n;
        printf("请输入想存几个值:");
        scanf("%d",&n);
        while(flag != 1) {
        	count ++;
        	STU *point = malloc(sizeof(STU));
        	memset(point,0,sizeof(STU));
         	printf("请输入age:");
         	scanf("%d",&point->age);
         	printf("请输入name:");
         	scanf("%s",point->name);
         	printf("请输入score:");
         	scanf("%f",&point->score);
         	p->next = point;
         	point->next = NULL;
         	p = point;
         	if(count == n) {
             		flag = 1;
         	}
	}
             p = p->next;
     
	// 发送一条消息
	STU *num = head->next;	
	struct msgbuf msg;
	while(num != NULL) {
		msg.mtype = 1;
		memcpy(msg.mtext,num,sizeof(STU));
		ret = msgsnd(msgid, &msg, sizeof(struct msgbuf) - sizeof(long), 0);
        	if (ret == -1) {
        		perror("msgsnd");  // 输出错误信息
        		exit(-1);          // 遇到错误退出程序
         	   }
		num = num -> next;
		}
	// 再单独发送完成标志
    msg.mtype = 1;
    memset(msg.mtext, 0, sizeof(msg.mtext));
    strcpy(msg.mtext, "EOF");
    ret = msgsnd(msgid, &msg, sizeof(msg.mtext), 0);
    if (ret == -1) {
        perror("msgsnd");
        exit(-1);
    }
	// 释放内存
    p = head;
    while (p != NULL) {
        STU *temp = p;
        p = p->next;
        free(temp);
    }

	struct msgbuf data;
	memset(&data,0,sizeof(data));
	ret = msgrcv(msgid,&data,sizeof(struct msgbuf) - sizeof(long),2,0);
	if(ret == -1)
	{
		perror("msgrcv");
		exit(-1);
	}

	printf("%s\n",data.mtext);
    return 0;
}
